
package com.kugou.game.sdk.hotfix;

import com.kugou.download.DownloadFile;
import com.kugou.download.FileDownloader;
import com.kugou.download.IProgressListener;
import com.kugou.game.sdk.core.FolderManager;
import com.kugou.game.sdk.core.SDKControler;
import com.kugou.game.sdk.download.DownloadServiceUtil;
import com.kugou.game.sdk.protocol.RequestPatchInfoTask;
import com.kugou.game.sdk.protocol.RequestPatchInfoTask.PatchInfoResponse;
import com.kugou.game.sdk.utils.FileUtil;
import com.kugou.game.sdk.utils.MD5Util;

import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 描述:补丁帮助类
 *
 * @author wcj
 * @since 2016年3月14日 下午4:56:34
 */
public class HotFixHelper {

    private static final String TAG = "HotFixHelper";

    // 线程池
    private static ExecutorService mExecutorService = Executors.newCachedThreadPool();

    /**
     * 对比本地补丁和远程补丁信息，远程有新补丁，下载，打补丁
     */
    public static void checkPatchInfo() {

        mExecutorService.execute(new Runnable() {

            @Override
            public void run() {
                RequestPatchInfoTask task = new RequestPatchInfoTask();
                PatchInfoResponse response = task.request();

                if (response != null && response.isOk()) {
                    Log.d(TAG, "get patch info success");
                    if (isNewPatch(response.getPatchInfo())) {
                        Log.d(TAG, "need download patch");
                        downloadPatchFile(response.getPatchInfo());
                    } else {
                        Log.d(TAG, "do not need download patch");
                    }
                } else if (response != null && !TextUtils.isEmpty(response.getPrompt())) {
                    Log.d(TAG, response.getPrompt());
                } else {
                    Log.d(TAG, "network failed");
                }
            }
        });
    }

    public static void downloadPatchFile(final PatchInfo info) {
        Log.d(TAG, "download the remote patch");
        try {
            DownloadServiceUtil.download(info.getPatchUrl(), FolderManager.PATCH_TEMP_PATH,
                    new IProgressListener() {

                        @Override
                        public void onProgressChanged(DownloadFile file, int state) {

                            if (state == FileDownloader.FINISH) {
                                // TO DO 下载成功打补丁
                                Log.d(TAG, "download the remote patch success");

                                try {
                                    // 对比md5，一致，打补丁
                                    Log.d(TAG, "check md5");
                                    if (MD5Util.getFileMD5String(
                                            new File(FolderManager.PATCH_TEMP_PATH))
                                            .equalsIgnoreCase(info.getPatchMd5())) {
                                        Log.d(TAG, "move patch file");

                                        String patchFileName = "patch_" + info.getSdkVersionCode()
                                                + "_" + info.getPatchId() + ".jar";

                                        // 复制文件
                                        FileUtil.writeFile(SDKControler.getContext()
                                                .getApplicationInfo().dataDir
                                                + File.separator
                                                + MultiDex.PATCH_FOLDER_NAME
                                                + File.separator
                                                + patchFileName, new FileInputStream(new File(
                                                FolderManager.PATCH_TEMP_PATH)));

                                        Log.d(TAG, "delete sdcard patch file");
                                        FileUtil.deleteFile(FolderManager.PATCH_TEMP_PATH);
                                        Log.d(TAG, "move success");
                                        MultiDex.loadPatch(SDKControler.getContext(),
                                                info.getSdkVersionCode());
                                        Log.d(TAG, "load patch");
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }

                            } else if (state == FileDownloader.DOWNLOADING) {
                                Log.d(TAG, "downloading the remote patch");
                            }

                        }

                        @Override
                        public void onError(DownloadFile arg0, int arg1) {
                            // 下载失败删除下载文件
                            FileUtil.deleteFile(FolderManager.PATCH_TEMP_PATH);
                            Log.d(TAG, "download the remote patch failed");
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static boolean isNewPatch(PatchInfo remotePatch) {
        PatchInfo localPatch = null;
        try {
            localPatch = loadLastLocalPatchInfo(remotePatch.getSdkVersionCode());
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (localPatch != null && localPatch.getPatchId() == remotePatch.getPatchId()
                && localPatch.getPatchMd5().equals(remotePatch.getPatchMd5())) {
            return false;
        }

        return true;
    }

    private static PatchInfo loadLastLocalPatchInfo(int sdkVersionCode) throws IOException {

        PatchInfo patchInfo = new PatchInfo();

        File patchDir = new File(SDKControler.getContext().getApplicationInfo().dataDir,
                MultiDex.PATCH_FOLDER_NAME);
        if (!patchDir.exists() || patchDir.list().length == 0) {
            return null;
        }
        File[] patchs = patchDir.listFiles();
        File maxPatchFile = null;
        int maxPatchCode = -1;
        if (patchs.length > 0) {
            maxPatchFile = patchs[0];
        }
        for (File file : patchs) {
            try {
                if (!file.getName().endsWith(".jar")) {
                    continue;
                }
                String fileName = file.getName().substring(0, file.getName().length() - 4);
                int versionCode = Integer.valueOf(fileName.split("_")[1]);
                int patchCode = Integer.valueOf(fileName.split("_")[2]);

                if (versionCode != sdkVersionCode) {
                    continue;
                }

                if (patchCode > maxPatchCode) {
                    maxPatchCode = patchCode;
                    maxPatchFile = file;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (maxPatchFile == null) {
            return null;
        } else {
            patchInfo.setSdkVersionCode(sdkVersionCode);
            patchInfo.setPatchId(maxPatchCode);
            patchInfo.setPatchMd5(MD5Util.getFileMD5String(maxPatchFile));
        }

        return patchInfo;
    }
}
